#include "ImageStream.hpp"
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <format>
#include <cstring>
#include <unistd.h>

ImageStream::ImageStream(const std::string& uuid)
{
  sharefd=shm_open(std::format("/SUPERMATRIX_REALTIME_IMAGE_MEM_{}",uuid).c_str(),O_RDONLY | O_EXCL,S_IRUSR);
  if(sharefd<0)
    throw std::runtime_error("Can't open sharemem");
  struct stat buf;
  if(fstat(sharefd,&buf))
    throw std::runtime_error("Can't get sharemem status");
  imagesize=buf.st_size-sizeof(int64_t);
  sharemem=(unsigned char*)mmap(nullptr,buf.st_size,PROT_READ,MAP_SHARED,sharefd,0);
  if(sharemem==MAP_FAILED)
    throw std::runtime_error("Can't mmap sharemem");

  sem=sem_open(std::format("/SUPERMATRIX_REALTIME_IMAGE_SEM_{}",uuid).c_str(),O_EXCL);
  if(sem==nullptr)
    throw std::runtime_error("Can't open semaphore");
}

ImageStream::~ImageStream()
{
  close(sharefd);
  sem_destroy(sem);
}

long ImageStream::GetRealtimeImg(unsigned char* image)
{
  if(sem_wait(sem))
    throw std::runtime_error("Can't lock memory");
  int64_t frameid;
  memcpy(&frameid,sharemem,sizeof(int64_t));
  memcpy(image,sharemem+sizeof(int64_t),imagesize);
  if(sem_post(sem))
    throw std::runtime_error("Can't unlock memory");
  return frameid;
}

long ImageStream::GetSize()
{
  return imagesize;
}

